<?php

namespace App\Server;

use App\Utils\JT808\JT808;
use Exception;
use Hyperf\Contract\OnReceiveInterface;
use Jundayw\JTT808\Message;
use Jundayw\JTT808\MessageRequest\Message0001Request;
use Jundayw\JTT808\MessageRequest\Message0002Request;
use Jundayw\JTT808\MessageRequest\Message0100Request;
use Jundayw\JTT808\MessageRequest\Message0200Request;
use Jundayw\JTT808\MessageResponse\Message8001Response;
use Jundayw\JTT808\MessageResponse\Message8100Response;
use ModbusTcpClient\Composer\Read\ReadRegistersBuilder;
use ModbusTcpClient\Packet\ModbusFunction\ReadHoldingRegistersRequest;
use ModbusTcpClient\Packet\RtuConverter;
use Swoole\Timer;
use function Hyperf\Coroutine\co;

class TcpServer implements OnReceiveInterface
{
    public function onReceive($server, int $fd, int $reactorId, string $data): void
    {
        //接收到的消息
        //解析报文 二进制数据流转成十六进制的
        $get_data = unpack('H*', $data)[1];
        if (str_contains($get_data,"7e")){
            $this->getJtt808($data,$server,$fd);
        }else{
            //        Timer::tick(3000,function ()use($server,$fd){
//            $server->send($fd,'kQaUT0CfDbvFGv2');
//        });
            // 将请求字符串转换为十六进制数组
//        $hexArray = str_split($get_data, 4);
//        // 解析地址和数量
//        $startAddress=hexdec($hexArray[1]);
//        $unitID = 1; // RTU packet slave id equivalent is Modbus TCP unitId
//
//        $fc3requests = ReadRegistersBuilder::newReadHoldingRegisters('no_address', $unitID)
//        ->uint16($startAddress, 'address2_value')
//        ->build();
//        $tcpPacket = new ReadHoldingRegistersRequest($startAddress, 1, 1);
//        $rtuPacket = RtuConverter::toRtu($tcpPacket);
//var_dump(unpack('H*', $rtuPacket)[1]);
        }
        $server->send($fd,'ok');
    }
    private function getJt808($data)
    {
        $JT808 = new JT808();
        //16进制数据
        $data16Arrays = $JT808->getTo16Bytes($data);
        foreach ($data16Arrays as $key => $data16Array) {
            //获取消息id
            $MessageId = $JT808->getMessageIdNumber($data16Array);
            //设备号
            $equipmentNumber = $JT808->getEquipmentNumber($data16Array);
            //平台流水号
            $systemNumbers = $JT808->getMessageNumberArray($data16Array);
            //位置信息上报获取
            if ($MessageId == '0200' && $equipmentNumber) {
                //报警信息
                $AlarmMessage = $JT808->getAlarmMessage($data16Array, 13);
                //状态
                $status = $JT808->getPositionStatus($data16Array, 17);
                //经度
                $Latitude = $JT808->getLatitude($data16Array, 21, 'i');
                //纬度
                $Longitude = $JT808->getLongitude($data16Array, 25, 'i');
                //高度
                $Height = $JT808->getHeight($data16Array, 29);
                //速度
                $Speed = $JT808->getSpeed($data16Array, 31);
                //方向
                $Direction = $JT808->getDirection($data16Array, 33);
                //时间
                $Datetime = $JT808->getDatetime($data16Array, 35);
                if ($Latitude && $Longitude) {
                    //执行你的逻辑
                }
                $data_value=[
                    "AlarmMessage"=>$AlarmMessage,
                    "status"=>$status,
                    "Latitude"=>$Latitude,
                    "Longitude"=>$Longitude,
                    "Height"=>$Height,
                    "Speed"=>$Speed,
                    "Direction"=>$Direction,
                    "Datetime"=>$Datetime,
                    "equipmentNumber"=>$equipmentNumber,
                    "systemNumbers"=>$systemNumbers,
                ];
                var_dump($data_value);

            }elseif ($MessageId==="0100"){
                //终端注册

            }
            //发送给客户端
            return $JT808->getVerifyNumberArray($data16Array);
        }
    }

    private function getJtt808($data,$server,$fd)
    {
        $conn = $server->connection_info($fd);
        try {
            $message = new Message();
            $message->decode($data);
            switch ($message->getMsgId()) {
                case '0100':
                    // 终端注册
                    $request = new Message0100Request($message);
                    //判断字符串中是否有空格
                    //车辆标识
                    $plateNumber = trim($request->plateNumber);
                    //终端ID
                    $terminalId = trim($request->terminalId);
                    if (str_contains($plateNumber,'')){
                        $plateNumber_data = explode('',$plateNumber);
                        $plateNumber= $plateNumber_data[1];
                        if (empty($terminalId)){
                            $terminalId= $plateNumber_data[0];
                        }
                    }
                    $manufacturerId = trim($request->manufacturerId);
                    if (str_contains($manufacturerId,"")){
                        $manufacturerId =str_replace('', '', $manufacturerId);
                    }
                    //终端型号
                    $terminalModel =trim($request->terminalModel);
                    if (str_contains($terminalModel,"")){
                        $terminalModel =str_replace('', '', $terminalModel);
                    }
                    //车牌颜色
                    $plateColor =trim($request->plateColor);
                    if (str_contains($plateColor,"")){
                        $plateColor =str_replace('', '', $plateColor);
                    }
                    //省ID
                    $provinceId = trim($request->provinceId);
                    if (str_contains($provinceId,"")){
                        $provinceId =str_replace('', '', $provinceId);
                    }
                    //市县域ID
                    $cityId = trim($request->cityId);
                    if (str_contains($cityId,"")){
                        $cityId =str_replace('', '', $cityId);
                    }
                    var_dump([
                        '省域ID' => $provinceId,
                        '市县域ID' => $cityId,
                        '制造商ID' => $manufacturerId,
                        '终端型号' => $terminalModel,
                        '终端ID' => $terminalId,
                        '车牌颜色' => $plateColor,
                        '车辆标识' => $plateNumber,
                    ]);
                    //判断设备是否已经注册
                    //$server->getClientInfo($fd)['uid'];
                    if (empty($conn['uid'])) {
                        //查询设备的id
                        $uid = 1;
                        //数据库中无该终端
                        //$code=4;
                        //终端已被注册
                        //$code=3;
                        //终端与程序进行绑定
                        $server->bind($fd,$uid);
                        $code=0;
                    }else{
                        //车辆已被注册
                        $code =1;
                    }
                    // 终端注册应答
                    $response = new Message8100Response($message);
                    $response->response($code, '123456');
                    $server->send($fd,$message->encode($response->response(0)));
                    //var_dump(bin2hex($message->encode($response)));
                    break;
                case '0200':
                    // 位置信息汇报
                    $request = new Message0200Request($message);
                    var_dump([
                        '报警标志' => $request->alarm,
                        '报警信息' => $request->alarmList,
                        '状态位标志' => $request->state,
                        '状态位信息' => $request->statusList,
                        '纬度' => $request->latitude,
                        '经度' => $request->longitude,
                        '高程' => $request->height,
                        '速度' => $request->speed,
                        '方向(范围为 0~359，表示度数)' => $request->direction,
                        '时间' => $request->time,
                        '扩展信息' => $request->extendList,
                    ]);
                    // 平台通用应答
                    $response = new Message8001Response($message);
                    $server->send($fd,$message->encode($response->response(0)));
                    break;
                case '0001':
                    //$request = new Message0001Request($message);
                    $response = new Message8100Response($message);
                    $server->send($fd,$message->encode($response->response(0, '123456')));
                    break;
                case '0002':
                    //心跳
                    //$request = new Message0002Request($message);
                    $response = new Message8001Response($message);
                    //每30秒发送一次心跳检测
                    Timer::tick(30000,function ()use($server,$message,$response,$fd){
                        $server->send($fd,$message->encode($response->response(0)));
                    });
                    $server->send($fd,$message->encode($response->response(0)));
                    break;
            }

        } catch (Exception $e) {
            var_dump('Eexception', $e->getMessage());
        }
    }
}